package cn.bertsir.zbar;


import cn.bertsir.zbar.Qr.Config;
import cn.bertsir.zbar.Qr.ImageScanner;
import cn.bertsir.zbar.Qr.ScanResult;
import cn.bertsir.zbar.Qr.Symbol;
import cn.bertsir.zbar.utils.Log;
import cn.bertsir.zbar.utils.QRUtils;
import cn.bertsir.zbar.view.ScanView;
import cn.bertsir.zbar.view.ViewfinderView;
import com.lzy.imagepicker.ImagePicker;
import com.lzy.imagepicker.bean.ImageItem;
import com.lzy.imagepicker.loader.ImageLoader;
import com.lzy.imagepicker.ui.ImageGridAbility;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.ImageSize;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.ability.DataAbilityHelper;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.*;
import ohos.agp.components.Image;
import ohos.agp.components.surfaceprovider.SurfaceProvider;
import ohos.agp.graphics.Surface;
import ohos.agp.graphics.SurfaceOps;
import ohos.agp.utils.Color;
import ohos.agp.utils.TextTool;
import ohos.agp.window.dialog.CommonDialog;
import ohos.agp.window.dialog.ToastDialog;
import ohos.app.Context;
import ohos.app.Environment;
import ohos.app.dispatcher.TaskDispatcher;
import ohos.app.dispatcher.task.TaskPriority;
import ohos.bundle.AbilityInfo;
import ohos.data.rdb.ValuesBucket;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.global.resource.RawFileDescriptor;
import ohos.media.camera.CameraKit;
import ohos.media.camera.device.*;
import ohos.media.common.BufferInfo;
import ohos.media.common.Source;
import ohos.media.image.*;
import ohos.media.image.common.ImageFormat;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Rect;
import ohos.media.image.common.Size;
import ohos.media.photokit.metadata.AVStorage;
import ohos.media.player.Player;
import ohos.multimodalinput.event.MmiPoint;
import ohos.multimodalinput.event.TouchEvent;
import ohos.sensor.agent.CategoryLightAgent;
import ohos.sensor.bean.CategoryLight;
import ohos.sensor.data.CategoryLightData;
import ohos.sensor.listener.ICategoryLightDataCallback;
import ohos.utils.net.Uri;

import java.io.*;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Locale;
import java.util.UUID;

import static ohos.media.camera.device.Camera.FrameConfigType.FRAME_CONFIG_PREVIEW;
import static ohos.media.camera.params.Metadata.FlashMode.*;

/**
 * 二维码扫描 ability
 */
public class QRActivity extends Ability implements ImageReceiver.IImageArrivalListener, Component.ClickedListener, Component.TouchEventListener {
    private static final int SCREEN_WIDTH = 2340;
    private static final int SCREEN_HEIGHT = 1080;
    private static final int IMAGE_RCV_CAPACITY = 5;
    private SurfaceProvider surfaceProvider;
    private ImageReceiver imageReceiver;
    private Camera cameraDevice;
    private Surface previewSurface;
    private EventHandler creamEventHandler;
    private boolean isOpen = true;
    private FrameConfig.Builder framePreviewConfigBuilder;
    private boolean isShowTopBar = true;
    private StackLayout topBar;
    private boolean isSound = true;
    private Player mPlayer;


    private ScanView sv;
    private ohos.agp.components.Image mo_scanner_back;
    private ohos.agp.components.Image iv_flash;
    private ohos.agp.components.Image iv_album;
    private static final String TAG = "QRActivity";
    private Text textDialog;
    private Text tv_title;
    private Text tv_des;
    private QrConfig options;

    private String cropTempPath = "cropQr.jpg";
    private Slider vsb_zoom;
    private CommonDialog progressDialog;
    private float oldDist = 1f;
    private long lastResultTime = 0;
    private float zoom = 0;
    private ViewfinderView viewfinderView;
    ImageScanner scanner;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_capture);
        options = (QrConfig) intent.getSerializableParam(QrConfig.EXTRA_THIS_CONFIG);
        scanner = new ImageScanner();
        if (options.getScan_type() == QrConfig.TYPE_QRCODE) {
            scanner.setConfig(Symbol.NONE, Config.ENABLE, 0);
            scanner.setConfig(Symbol.QRCODE, Config.ENABLE, 1);
        } else if (options.getScan_type() == QrConfig.TYPE_BARCODE) {
            scanner.setConfig(Symbol.NONE, Config.ENABLE, 0);
            scanner.setConfig(Symbol.CODE128, Config.ENABLE, 1);
            scanner.setConfig(Symbol.CODE39, Config.ENABLE, 1);
            scanner.setConfig(Symbol.EAN13, Config.ENABLE, 1);
            scanner.setConfig(Symbol.EAN8, Config.ENABLE, 1);
            scanner.setConfig(Symbol.UPCA, Config.ENABLE, 1);
            scanner.setConfig(Symbol.UPCE, Config.ENABLE, 1);
            scanner.setConfig(Symbol.UPCE, Config.ENABLE, 1);
        } else if (Symbol.scanType == QrConfig.TYPE_ALL) {
            scanner.setConfig(Symbol.NONE, Config.X_DENSITY, 3);
            scanner.setConfig(Symbol.NONE, Config.Y_DENSITY, 3);
        } else if (Symbol.scanType == QrConfig.TYPE_CUSTOM) {
            scanner.setConfig(Symbol.NONE, Config.ENABLE, 0);
            scanner.setConfig(Symbol.scanFormat, Config.ENABLE, 1);
        } else {
            scanner.setConfig(Symbol.NONE, Config.X_DENSITY, 3);
            scanner.setConfig(Symbol.NONE, Config.Y_DENSITY, 3);
        }
        isShowTopBar = intent.getBooleanParam("isShowTopBar", true);
        isSound = intent.getBooleanParam("isSound", true);
        if (options.isAuto_light()) {
            initLight();
        }
        switch (options.getSCREEN_ORIENTATION()) {
            case QrConfig.SCREEN_LANDSCAPE:
                setDisplayOrientation(AbilityInfo.DisplayOrientation.LANDSCAPE);
                onStop();
                break;
            case QrConfig.SCREEN_PORTRAIT:
                setDisplayOrientation(AbilityInfo.DisplayOrientation.PORTRAIT);
                break;
            case QrConfig.SCREEN_SENSOR:
                setDisplayOrientation(AbilityInfo.DisplayOrientation.UNSPECIFIED);
                break;
            default:
                setDisplayOrientation(AbilityInfo.DisplayOrientation.PORTRAIT);
                break;
        }
        topBar = (StackLayout) findComponentById(ResourceTable.Id_top_bar);

        topBar.setVisibility(isShowTopBar ? Component.VISIBLE : Component.HIDE);

        getWindow().setTransparent(true);
        if (creamEventHandler == null) {
            creamEventHandler = new EventHandler(EventRunner.create("CameraBackground"));
        }
        if (isSound) {
            initBeepSound();
        }
        sv = (ScanView) findComponentById(ResourceTable.Id_sv);
        sv.setType(options.getScan_view_type());
        initSurface();

        findComponentById(ResourceTable.Id_txt_open_flash).setClickedListener(this);
        findComponentById(ResourceTable.Id_txt_close).setClickedListener(this);
        findComponentById(ResourceTable.Id_iv_album).setClickedListener(this);

        initBeepSound();


        mo_scanner_back = (ohos.agp.components.Image) findComponentById(ResourceTable.Id_txt_close);
        mo_scanner_back.setClickedListener(this);
        mo_scanner_back.setImageAndDecodeBounds(options.getBackImgRes());

        iv_flash = (ohos.agp.components.Image) findComponentById(ResourceTable.Id_txt_open_flash);
        iv_flash.setClickedListener(this);
//        iv_flash.setImageAndDecodeBounds(options.getLightImageRes());


        iv_album = (ohos.agp.components.Image) findComponentById(ResourceTable.Id_iv_album);
        iv_album.setClickedListener(this);
//        iv_album.setImageAndDecodeBounds(options.getAblumImageRes());

        tv_title = (Text) findComponentById(ResourceTable.Id_tv_title);

        tv_des = (Text) findComponentById(ResourceTable.Id_tv_des);

        vsb_zoom = (Slider) findComponentById(ResourceTable.Id_vsb_zoom);

        iv_album.setVisibility(options.isShow_light() ? Component.VISIBLE : Component.HIDE);
        topBar.setVisibility(options.isShow_title() ? Component.VISIBLE : Component.HIDE);
        iv_flash.setVisibility(options.isShow_light() ? Component.VISIBLE : Component.HIDE);
        iv_album.setVisibility(options.isShow_album() ? Component.VISIBLE : Component.HIDE);
        tv_des.setVisibility(options.isShow_des() ? Component.VISIBLE : Component.HIDE);
        vsb_zoom.setVisibility(options.isShow_zoom() ? Component.VISIBLE : Component.HIDE);

        tv_des.setText(options.getDes_text());
        tv_title.setText(options.getTitle_text());
//        fl_title.setBackground(options.getTITLE_BACKGROUND_COLOR());
        tv_title.setTextColor(new Color(options.getTITLE_TEXT_COLOR()));

        sv.setCornerColor(options.getCORNER_COLOR());
        sv.setLineSpeed(options.getLine_speed());
        sv.setLineColor(options.getLINE_COLOR());
        sv.setScanLineStyle(options.getLine_style());


//        setSeekBarColor(vsb_zoom, options.getCORNER_COLOR());
        vsb_zoom.setValueChangedListener(new Slider.ValueChangedListener() {
            @Override
            public void onProgressUpdated(Slider slider, int progress, boolean b) {
                setZoom(progress / 10f);
            }

            @Override
            public void onTouchStart(Slider slider) {

            }

            @Override
            public void onTouchEnd(Slider slider) {

            }


        });

    }


    @Override
    public void onClick(Component component) {
        if (component.getId() == ResourceTable.Id_txt_open_flash) {
            if (isOpen) {
                isOpen = false;
//                txtOpenFlash.setText("关闭闪光灯");
                openFlashlight();
            } else {
                isOpen = true;
//                txtOpenFlash.setText("打开闪光灯");
                closeFlashlight();
            }
        } else if (component.getId() == ResourceTable.Id_txt_close) {
            terminateAbility();
        } else if (component.getId() == ResourceTable.Id_iv_album) {
            openSystemPhoto();
        }
    }

    void openSystemPhoto() {
        ImageLoaderConfiguration config = ImageLoaderConfiguration.createDefault(this);
        com.nostra13.universalimageloader.core.ImageLoader.getInstance().init(config);

        ImagePicker imagePicker = ImagePicker.getInstance();
        imagePicker.setImageLoader(new UILImageLoader());   //设置图片加载器
        imagePicker.setShowCamera(false);  //显示拍照按钮
        imagePicker.setCrop(false);        //允许裁剪（单选才有效）
        imagePicker.setMultiMode(false);
        ArrayList<ImageItem> images = new ArrayList<>();
        Intent intent = new Intent();
        Operation operation = new Intent.OperationBuilder()
                .withDeviceId("")
                .withBundleName(getBundleName())
                .withAbilityName(ImageGridAbility.class.getName())
                .build();
        intent.setOperation(operation);
        intent.setParam(ImageGridAbility.EXTRAS_IMAGES, images);
        startAbilityForResult(intent, 100);
    }

    ArrayList<ImageItem> images;

    @Override
    protected void onAbilityResult(int requestCode, int resultCode, Intent resultData) {
        try {
            super.onAbilityResult(requestCode, resultCode, resultData);
            if (resultCode == ImagePicker.RESULT_CODE_ITEMS) {
                if (resultData != null && requestCode == 100) {
                    images = (ArrayList<ImageItem>) resultData.getSerializableParam(ImagePicker.EXTRA_RESULT_ITEMS);
                    DataAbilityHelper helper = DataAbilityHelper.creator(this);
                    FileDescriptor fd = helper.openFile(Uri.parse(images.get(0).uriSchema), "r");
                    ImageSource imageSource = ImageSource.create(fd, null);
                    recognitionLocation(imageSource);
                }
            }
        } catch (Exception e) {
            images = new ArrayList<>();
        }
    }

    void openFlashlight() {
        if (cameraDevice != null) {
            framePreviewConfigBuilder.setFlashMode(FLASH_ALWAYS_OPEN);
            cameraDevice.triggerLoopingCapture(framePreviewConfigBuilder.build());
        }
    }

    void closeFlashlight() {
        if (cameraDevice != null) {
            framePreviewConfigBuilder.setFlashMode(FLASH_CLOSE);
            cameraDevice.triggerLoopingCapture(framePreviewConfigBuilder.build());
        }
    }

    /**
     * 相机设置焦距
     *
     * @param ratio 焦距
     */
    void setZoom(float ratio) {
        // 预览帧变焦值变更
        framePreviewConfigBuilder = cameraDevice.getFrameConfigBuilder(FRAME_CONFIG_PREVIEW);
        framePreviewConfigBuilder.addSurface(previewSurface);
        framePreviewConfigBuilder.addSurface(imageReceiver.getRecevingSurface());
        framePreviewConfigBuilder.setZoom(ratio);
        cameraDevice.triggerLoopingCapture(framePreviewConfigBuilder.build());
    }

    private void initSurface() {
        if (surfaceProvider != null) {
            return;
        }
        DependentLayout dependentLayout = (DependentLayout) findComponentById(ResourceTable.Id_surface_container);
        surfaceProvider = new SurfaceProvider(this);
        dependentLayout.addComponent(
                surfaceProvider,
                new DependentLayout.LayoutConfig(
                        ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_PARENT));

        if (options.isOnly_center()) {
            viewfinderView = new ViewfinderView(this);

            dependentLayout.addComponent(
                    viewfinderView,
                    new DependentLayout.LayoutConfig(
                            ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_PARENT));
        } else {
            sv.setVisibility(Component.VISIBLE);
        }
        surfaceProvider.pinToZTop(false);
        if (surfaceProvider != null) {
            surfaceProvider.getSurfaceOps().get().addCallback(new SurfaceCallBack());
        }
        if (options.isFinger_zoom()) {
            dependentLayout.setTouchEventListener(this::onTouchEvent);
        }
    }

    private boolean isAnalyze = false;
    public static final int VIDEO_WIDTH = 640;
    public static final int VIDEO_HEIGHT = 480;

    @Override
    public void onImageArrival(ImageReceiver imageReceiver) {
        if (options.isOnly_center()) {
            try {
                ohos.media.image.Image image = imageReceiver.readLatestImage();
                if (image == null) {
                    return;
                }
                if (isAnalyze) {
                    image.release();
                    return;
                }
                isAnalyze = true;
                ohos.media.image.Image.Component component = image.getComponent(ImageFormat.ComponentType.JPEG);
                byte[] bytes = new byte[component.remaining()];
                ByteBuffer buffer = component.getBuffer();
                buffer.get(bytes);
                ImageSource imageSource = ImageSource.create(bytes, new ImageSource.SourceOptions());
                ImageSource.DecodingOptions options = new ImageSource.DecodingOptions();
                if (viewfinderView != null) {
                    options.rotateDegrees = 90f;
                    options.desiredRegion =
                            new Rect(
                                    viewfinderView.getFramingRect().top,
                                    viewfinderView.getFramingRect().left,
                                    viewfinderView.getFramingRect().getHeight(),
                                    viewfinderView.getFramingRect().getWidth());
                }
//            System.out.println("======Rect======="+sv.getLeft()+"___"+ sv.getTop()+"___"+ sv.getWidth()+"___"+sv.getHeight());
                PixelMap map = imageSource.createPixelmap(options);
//            String result=QRUtils.getInstance().decodeQRcodeByZxing(map);
//           saveImage("test",map);
                String result = QRUtils.parseInfoFromBitmap(map);
//            System.out.println("====result="+result);
                if (result != null) {
                    if (System.currentTimeMillis() - lastResultTime > this.options.getLoop_wait_time()) {
                        ScanResult scanResult = new ScanResult();
                        scanResult.setContent(result);
                        scanResult.setType(ScanResult.CODE_QR);
                        lastResultTime = System.currentTimeMillis();
                        onScanResult(scanResult);
                    }
                }
                image.release();
                isAnalyze = false;

            } catch (Exception e) {
                System.out.println("====Exception=" + e.getMessage());
            }
        } else {

            ohos.media.image.Image mImage = imageReceiver.readNextImage();
            if (mImage != null) {
                BufferInfo bufferInfo = new BufferInfo();
                ByteBuffer mBuffer;
                byte[] YUV_DATA = new byte[VIDEO_HEIGHT * VIDEO_WIDTH * 3 / 2];
                int i;
                //采集YUV格式数据
                mBuffer = mImage.getComponent(ImageFormat.ComponentType.YUV_Y).getBuffer();
                for (i = 0; i < VIDEO_WIDTH * VIDEO_HEIGHT; i++) {
                    YUV_DATA[i] = mBuffer.get(i);
                }
                mBuffer = mImage.getComponent(ImageFormat.ComponentType.YUV_V).getBuffer();
                for (i = 0; i < VIDEO_WIDTH * VIDEO_HEIGHT / 4; i++) {
                    YUV_DATA[(VIDEO_WIDTH * VIDEO_HEIGHT) + i * 2] =
                            mBuffer.get(i * 2);
                }
                mBuffer = mImage.getComponent(ImageFormat.ComponentType.YUV_U).getBuffer();
                for (i = 0; i < VIDEO_WIDTH * VIDEO_HEIGHT / 4; i++) {
                    YUV_DATA[(VIDEO_WIDTH * VIDEO_HEIGHT) + i * 2 + 1] = mBuffer.get(i * 2);
                }
                bufferInfo.setInfo(0, VIDEO_WIDTH * VIDEO_HEIGHT * 3 / 2, mImage.getTimestamp(), 0);
                cn.bertsir.zbar.Qr.Image barcode = new cn.bertsir.zbar.Qr.Image(mImage.getImageSize().width, mImage.getImageSize().height, "Y800");
                barcode.setData(YUV_DATA);
                if (scanner.scanImage(barcode) != 0) {
                    for (Symbol sym : scanner.getResults()) {
                        if (System.currentTimeMillis() - lastResultTime > this.options.getLoop_wait_time()) {
                            ScanResult scanResult = new ScanResult();
                            scanResult.setContent(sym.getData());
                            scanResult.setType(sym.getType());
                            lastResultTime = System.currentTimeMillis();
                            onScanResult(scanResult);
                        }
                    }
                }
                mImage.release();
                isAnalyze = false;
                return;
            }
        }
    }

    public void onScanResult(ScanResult result) {
        if (result.getContent() == null) {
            return;
        }
        if (options.isPlay_sound()) {
            mPlayer.prepare();
            mPlayer.play();
        }
        if (options.isShow_vibrator()) {
            QRUtils.getInstance().getVibrator();
        }
//            if (cp != null) {
//                cp.setFlash(false);
//            }
        QrManager.getInstance().getResultCallback().onScanSuccess(result);
        if (!options.isLoop_scan()) {
            terminateAbility();
        }
    }

    private int time = 0;

    private static final String IMG_FILE_PREFIX = "IMG_";

    private static final String IMG_FILE_TYPE = ".jpg";

    private void saveImage(byte[] bitmapPixels) {
        FileOutputStream output = null;
        try {
            String fileName = IMG_FILE_PREFIX + UUID.randomUUID() + IMG_FILE_TYPE;
            File targetFile = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), fileName);
            output = new FileOutputStream(targetFile);
            output.write(bitmapPixels);
        } catch (IOException e) {
            Log.debug("saveImage ERROR =" + e.getMessage());
        } finally {
            try {
                if (output != null) {
                    output.close();
                }

            } catch (IOException e) {
                Log.error(e.getMessage());
            }
        }
    }

    private void initBeepSound() {
        try {
            RawFileDescriptor filDescriptor = getResourceManager().getRawFileEntry(options.getDing_path()).openRawFileDescriptor();
            Source source = new Source(filDescriptor.getFileDescriptor(), filDescriptor.getStartPosition(), filDescriptor.getFileSize());
            mPlayer = new Player(this);
            mPlayer.setSource(source);
        } catch (Exception e) {
            Log.error(e.getMessage());
        }
    }

    @Override
    public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
        switch (touchEvent.getAction()) {
            case TouchEvent.OTHER_POINT_DOWN:
                if (touchEvent.getPointerCount() == 2) {
                    oldDist = getFingerSpacing(touchEvent);
                }
                break;
            case TouchEvent.POINT_MOVE:
                if (touchEvent.getPointerCount() == 2) {
                    float newDist = getFingerSpacing(touchEvent);
                    if (newDist > oldDist) {//放大
                        if (zoom < 10) {
                            zoom += 0.1;
                        }
                    } else if (newDist < oldDist) { //缩小
                        if (zoom > 0) {
                            zoom -= 0.1f;
                        }
                    }
                    setZoom(zoom); //设置缩放比例
                    oldDist = newDist;
                }
                break;
        }
        return true;
    }

    public float getFingerSpacing(TouchEvent touchEvent) {
        MmiPoint p = touchEvent.getPointerPosition(0);
        float px = p.getX();
        float py = p.getY();
        MmiPoint p1 = touchEvent.getPointerPosition(1);
        float px1 = p1.getX();
        float py1 = p1.getY();
        float x = px - px1;
        float y = py - py1;
        return (float) Math.sqrt(x * x + y * y);
    }

    /**
     * SurfaceCallBack
     *
     * @since 2020-09-03
     */
    class SurfaceCallBack implements SurfaceOps.Callback {
        @Override
        public void surfaceCreated(SurfaceOps callbackSurfaceOps) {
            if (callbackSurfaceOps != null) {
                callbackSurfaceOps.setFixedSize(SCREEN_WIDTH, SCREEN_HEIGHT);
            }
            openCamera();
        }

        @Override
        public void surfaceChanged(SurfaceOps callbackSurfaceOps, int format, int width, int height) {
        }

        @Override
        public void surfaceDestroyed(SurfaceOps callbackSurfaceOps) {
        }
    }

    private void openCamera() {
        if (options.isOnly_center()) {
            imageReceiver = ImageReceiver.create(SCREEN_WIDTH, SCREEN_HEIGHT, ImageFormat.JPEG, IMAGE_RCV_CAPACITY);
        } else {
            imageReceiver = ImageReceiver.create(VIDEO_WIDTH, VIDEO_HEIGHT, ImageFormat.YUV420_888, 10);

        }
        imageReceiver.setImageArrivalListener(this);

        CameraKit cameraKit = CameraKit.getInstance(getApplicationContext());
        String[] cameraList = cameraKit.getCameraIds();
        String cameraId = null;
        for (
                String id : cameraList) {
            if (cameraKit.getCameraInfo(id).getFacingType() == CameraInfo.FacingType.CAMERA_FACING_BACK) {
                cameraId = id;
            }
        }
        if (cameraId == null) {
            return;
        }

        CameraStateCallbackImpl cameraStateCallback = new CameraStateCallbackImpl();
        cameraKit.createCamera(cameraId, cameraStateCallback, creamEventHandler);
    }

    class CameraStateCallbackImpl extends CameraStateCallback {
        CameraStateCallbackImpl() {
        }

        @Override
        public void onCreated(Camera camera) {
            Log.debug("create camera onCreated");
            Log.debug("surfaceProvider==null  =" + (surfaceProvider));
            if (surfaceProvider == null) {
                return;
            }
            previewSurface = surfaceProvider.getSurfaceOps().get().getSurface();
            if (previewSurface == null) {
                Log.debug("create camera filed, preview surface is null");
                return;
            }
            // Wait until the preview surface is created.
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Log.debug("Waiting to be interrupted");
            }
            CameraConfig.Builder cameraConfigBuilder = camera.getCameraConfigBuilder();
            cameraConfigBuilder.addSurface(previewSurface);
            cameraConfigBuilder.addSurface(imageReceiver.getRecevingSurface());
            if (surfaceProvider==null){
                return;
            }
            camera.configure(cameraConfigBuilder.build());

            cameraDevice = camera;

            framePreviewConfigBuilder = camera.getFrameConfigBuilder(FRAME_CONFIG_PREVIEW);
            framePreviewConfigBuilder.addSurface(imageReceiver.getRecevingSurface());
            framePreviewConfigBuilder.addSurface(previewSurface);
            camera.triggerLoopingCapture(framePreviewConfigBuilder.build());
        }

        @Override
        public void onConfigured(Camera camera) {
            Log.debug("onConfigured....");

            framePreviewConfigBuilder.setFlashMode(FLASH_AUTO);
            framePreviewConfigBuilder.addSurface(previewSurface);
            camera.triggerLoopingCapture(framePreviewConfigBuilder.build());
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (cameraDevice != null) {
            framePreviewConfigBuilder = null;
            try {
                cameraDevice.release();
                cameraDevice = null;
                surfaceProvider.clearFocus();
                surfaceProvider.removeFromWindow();
                surfaceProvider = null;
            } catch (Exception e) {
                Log.debug(e.getMessage());
            }
        }
        if (lightSensor != null) {
            categoryLightAgent.releaseSensorDataCallback(
                    lightDataCallback, lightSensor);
        }
    }

    private static final long INTERVAL = 100000000L;
    private CategoryLightAgent categoryLightAgent = new CategoryLightAgent();

    private ICategoryLightDataCallback lightDataCallback;

    private CategoryLight lightSensor;

    private void initLight() {
        lightDataCallback = new ICategoryLightDataCallback() {

            @Override
            public void onSensorDataModified(CategoryLightData categoryLightData) {
//                System.out.println("==========onSensorDataModified===="+categoryLightData.values[0]+"___"+categoryLightData.values[1]+"___"+categoryLightData.values[2]);
                if (framePreviewConfigBuilder != null) {
                    if (categoryLightData.values[0] < 10) {
                        openFlashlight();
                    } else {
                        closeFlashlight();
                    }
                }
            }

            @Override
            public void onAccuracyDataModified(CategoryLight categoryOrientation, int index) {
                // 使用变化的精度
            }

            @Override
            public void onCommandCompleted(CategoryLight categoryOrientation) {
                // 传感器执行命令回调
            }
        };

        lightSensor = categoryLightAgent.getSingleSensor(
                CategoryLight.SENSOR_TYPE_AMBIENT_LIGHT);
        if (lightSensor != null) {
            categoryLightAgent.setSensorDataCallback(
                    lightDataCallback, lightSensor, INTERVAL);
        }
    }

    public class UILImageLoader implements ImageLoader {

        @Override
        public void displayImage(Ability ability, String uriScheme, ohos.agp.components.Image imageView, int width, int height) {

            ImageSize size = new ImageSize(width, height);
            com.nostra13.universalimageloader.core.ImageLoader.getInstance().displayImage(uriScheme, imageView, size);
        }

        @Override
        public void displayImagePreview(Ability ability, String uriScheme, ohos.agp.components.Image imageView, int width, int height) {
            ImageSize size = new ImageSize(width, height);
            com.nostra13.universalimageloader.core.ImageLoader.getInstance().displayImage(uriScheme, imageView, size);
        }


        @Override
        public void clearMemoryCache() {
        }

    }

    /**
     * 识别本地
     *
     * @param imageSource imageSource
     */
    private void recognitionLocation(ImageSource imageSource) {
//        textDialog = showProgressDialog();
//        textDialog.setText("请稍后...");
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    TaskDispatcher refreshUITask = getContext().createParallelTaskDispatcher("", TaskPriority.DEFAULT);
                    refreshUITask.syncDispatch(() -> {
                        ScanResult scanResult = new ScanResult();
                        ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();
                        PixelMap pixelmap = imageSource.createThumbnailPixelmap(decodingOpts, true);
                        //优先使用zbar识别一次二维码
                        String zbar = QRUtils.getInstance().decodeQRcode(pixelmap);
//                        final String qrcontent2 =  QRUtils.parseInfoFromBitmap(pixelmap);
                        if (!TextTool.isNullOrEmpty(zbar)) {
                            scanResult.setContent(zbar);
                            scanResult.setType(ScanResult.CODE_QR);
                            QrManager.getInstance().getResultCallback().onScanSuccess(scanResult);
                            terminateAbility();
                        } else {
                            ImageSource.DecodingOptions decodingOpts3 = new ImageSource.DecodingOptions();
                            PixelMap pixelmap3 = imageSource.createThumbnailPixelmap(decodingOpts3, true);
                            //尝试用zxing再试一次识别二维码
                            String zxing = QRUtils.getInstance().decodeQRcodeByZxing(pixelmap3);
                            if (!TextTool.isNullOrEmpty(zxing)) {
                                scanResult.setContent(zxing);
                                scanResult.setType(ScanResult.CODE_QR);
                                QrManager.getInstance().getResultCallback().onScanSuccess(scanResult);
                                terminateAbility();
                            } else {
                                ImageSource.DecodingOptions decodingOpts2 = new ImageSource.DecodingOptions();
                                PixelMap pixelmap2 = imageSource.createThumbnailPixelmap(decodingOpts2, true);
                                //再试试是不是条形码
                                String qrcontent = QRUtils.getInstance().decodeBarcode(pixelmap2);
                                if (!TextTool.isNullOrEmpty(qrcontent)) {
                                    scanResult.setContent(qrcontent);
                                    scanResult.setType(ScanResult.CODE_BAR);
                                    QrManager.getInstance().getResultCallback().onScanSuccess(scanResult);
                                    terminateAbility();
                                } else {
                                    scanResult.setContent("未识别到二维码");
                                    QrManager.getInstance().getResultCallback().onScanSuccess(scanResult);
                                    terminateAbility();
                                }
                            }
                        }
                    });
                } catch (Exception e) {
                    System.out.println("===========识别异常");
                    closeProgressDialog();
                }
            }
        }).start();
    }

    public Text showProgressDialog() {
        progressDialog = new CommonDialog(this);
        Component component = LayoutScatter.getInstance(getContext())
                .parse(ResourceTable.Layout_dialog_loading, null, true);
        progressDialog.setSize(800, 500);
        progressDialog.setContentCustomComponent(component);
        progressDialog.show();
        ProgressBar pb_loading = (ProgressBar) component.findComponentById(ResourceTable.Id_pb_loading);
        ohos.agp.components.Image iv = (ohos.agp.components.Image) component.findComponentById(ResourceTable.Id_iv);
        Text tv_hint = (Text) component.findComponentById(ResourceTable.Id_tv_hint);

        return tv_hint;
    }

    public void closeProgressDialog() {
        try {
            if (progressDialog != null) {
                progressDialog.destroy();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onBackPressed() {
        super.onBackPressed();
        terminateAbility();
    }

    public void saveImage(String fileName, PixelMap pixelMap) {
        try {
            System.out.println("====PixelMap111111=" + pixelMap.getImageInfo().size.toString() + "-----" + pixelMap.getImageInfo().pixelFormat.name());

            ValuesBucket valuesBucket = new ValuesBucket();
            valuesBucket.putString(AVStorage.Images.Media.DISPLAY_NAME, fileName);
            valuesBucket.putString("relative_path", String.format(Locale.getDefault(),
                    "%s/Record/",
                    Environment.DIRECTORY_PICTURES));
            valuesBucket.putString(AVStorage.Images.Media.MIME_TYPE, "image/JPEG");
            //应用独占
            valuesBucket.putInteger("is_pending", 1);
            DataAbilityHelper helper = DataAbilityHelper.creator(this);
            int id = helper.insert(AVStorage.Images.Media.EXTERNAL_DATA_ABILITY_URI, valuesBucket);
            Uri uri = Uri.appendEncodedPathToUri(AVStorage.Images.Media.EXTERNAL_DATA_ABILITY_URI, String.valueOf(id));
            //这里需要"w"写权限
            FileDescriptor fd = helper.openFile(uri, "w");
            ImagePacker imagePacker = ImagePacker.create();
            ImagePacker.PackingOptions packingOptions = new ImagePacker.PackingOptions();
            OutputStream outputStream = new FileOutputStream(fd);
            packingOptions.format = "image/jpeg";
            packingOptions.quality = 90;
            boolean result = imagePacker.initializePacking(outputStream, packingOptions);
            if (result) {
                result = imagePacker.addImage(pixelMap);
                if (result) {
                    long dataSize = imagePacker.finalizePacking();
                }
            }
            outputStream.flush();
            outputStream.close();
            valuesBucket.clear();
            //解除独占
            valuesBucket.putInteger("is_pending", 0);
            helper.update(uri, valuesBucket, null);
        } catch (Exception e) {
            System.out.println("======saveImage=" + e.getMessage());
        }
    }
}
